package com.github.excel.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.github.excel.entity.args.excel.ExcelImportData;
import com.github.excel.listener.ExcelFileDataListener;
import com.github.excel.service.IExcelFileService;
import com.github.excel.utils.FileUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Service
public class ExcelFileServiceImpl implements IExcelFileService {

    @Override
    public List<Map<String, Object>> importExcelFile(MultipartFile file) {
        dealExcelFileUseEasyExcel(file);
        return new ArrayList<>();
    }

    @Override
    public void exportExcelFile() {
        String fileName = FileUtils.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
        List<ExcelImportData> exportData = this.getExportData();
        this.exportData(fileName,exportData);
//        //创建一个固定大小的线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);
//        //分段处理
//        int onceNum = 2;//单次处理的数据条数
//        int maxNum = exportData.size() / onceNum;
//        for (int i = 0; i <= maxNum; i++) {
//            int beginNum = i * onceNum;
//            if (beginNum >= exportData.size()) {
//                continue;
//            }
//            int endNum = (beginNum + onceNum) > exportData.size() ? exportData.size() : (beginNum + onceNum);
//            List<ExcelImportData> theList = exportData.subList(beginNum, endNum);
//            if (CollUtil.isNotEmpty(theList)) {
//                executor.execute(() -> {
//                    this.exportData(fileName,theList);
//                });
//            }
//        }
//        //启动线程池关闭序列
//        executor.shutdown();
//        //等待所有任务完成，或者在等待超时前的中断
//        try {
//            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
//        } catch (Exception e){
//            e.printStackTrace();
//        }
    }

    /**
     * poi处理excel文件
     */
//    private List<Map<String,Object>> dealExcelFileUsePOI(MultipartFile file){
//        List<Map<String,Object>> result = new ArrayList<>();
//        try {
//            //创建工作薄对象
//            Workbook workbook = new XSSFWorkbook(file.getInputStream());
//            //获取所有sheet页
//            int numberOfSheets = workbook.getNumberOfSheets();
//            //取所有sheet页中的数据放入到内存中（可能会导致内存溢出）
//            for (int number = 0;number < numberOfSheets;number++){
//                //获取sheet页
//                Sheet sheet = workbook.getSheetAt(number);
//                //sheet页总行数
//                int lastRowNum = sheet.getLastRowNum();
//                //从第二行开始遍历所有行
//                for (int i = 1;i <= lastRowNum;i++){
//                    //获取行数据
//                    Row row = sheet.getRow(i);
//                    //遍历所有单元格
//                    for (Cell cell : row){
//                        Map<String,Object> map = new HashMap<>();
//                        //根据不同数据类型处理数据
//                        map.put(sheet.getRow(0).getCell(cell.getAddress().getColumn()).getStringCellValue(),cell.getStringCellValue());
//                        result.add(map);
//                    }
//                }
//            }
//        } catch (Exception e){
//            e.printStackTrace();
//        }
//        return result;
//    }

    /**
     * 使用easyExcel读取多个sheet页使用线程池
     */
    private void dealExcelFileUseEasyExcel(MultipartFile file){
        try {
            //读取全部sheet
            List<ReadSheet> sheetList = EasyExcel.read(file.getInputStream()).build().excelExecutor().sheetList();
            //创建一个固定大小的线程池
            ExecutorService executor = Executors.newFixedThreadPool(sheetList.size());
            //遍历所有sheet
            for (ReadSheet sheet : sheetList){
                Integer sheetNo = sheet.getSheetNo();
                //向线程池提交一个任务，每个任务读取不同的sheet页
                executor.execute(() -> {
                    try {
                        EasyExcel.read(file.getInputStream(),ExcelImportData.class,new ExcelFileDataListener())
                                .sheet(sheetNo)//指定sheet号
                                .doRead();//开始读取操作
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
            //启动线程池关闭序列
            executor.shutdown();
            //等待所有任务完成，或者在等待超时前的中断
            try {
                executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
            } catch (Exception e){
                e.printStackTrace();
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 模拟数据
     */
    private static List<ExcelImportData> getExportData(){
        List<ExcelImportData> dataList = new ArrayList<>();
        ExcelImportData data1 = new ExcelImportData();
        data1.setFilterNumber("测试1");
        data1.setFilterName("测试2");
        ExcelImportData data2 = new ExcelImportData();
        data2.setFilterNumber("测试3");
        data2.setFilterName("测试4");
        ExcelImportData data3 = new ExcelImportData();
        data3.setFilterNumber("测试5");
        data3.setFilterName("测试6");
        dataList.add(data1);
        dataList.add(data2);
        dataList.add(data3);
        return dataList;
    }

    /**
     * 导出数据方法
     */
    private static void exportData(String fileName,List<ExcelImportData> exportDataList){
        //使用EasyExcel将数据写入到Excel文件
        EasyExcel.write(fileName,ExcelImportData.class).sheet("sheet1").doWrite(exportDataList);
    }
}
